package com.fita.entity.coupon;

import com.alibaba.fastjson.annotation.JSONField;
import com.demo2do.core.format.PersistentFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Type;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.util.Date;

/**
 * 优惠券批次
 * 
 * @author LZJ
 */
@Entity
@Table(name = "coupon_batch")
@PersistentFormat
@DynamicUpdate
@JsonIgnoreProperties(value={"hibernate_lazy_initializer","handler","fieldHandler"})
public class CouponBatch {

    @Id
    @GeneratedValue
    private Long id;
    
    /** 优惠券名称 来自模版 */
    private String templateName;

    /** 批次名称 */
    private String name;

    /** 发行日期 */
    private Date createTime;
    
    /** 有效期类型 */
    @Enumerated(EnumType.ORDINAL)
    private ExpireType expireType;

    /** 券有效期 - 开始时间 */
    @Type(type = "date")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JSONField(format = "yyyy-MM-dd")
    private Date effectiveStartDate;

    /** 券有效期 - 截止时间/过期时间 */
    @Type(type = "date")
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @JSONField(format = "yyyy-MM-dd")
    private Date effectiveEndDate;
    
    /** 券有效期 - 认领后固定天数*/
    private int effectiveDays;

    /** 本批次发行数量 */
    private int amount;
    
    /** 已发行数量 */
    private int releaseAmount;

    /** 已使用数 */
    private int usedAmount;

    /** 已认领数 */
    private int claimedAmount;

    /** 使用的优惠券模版*/
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @PersistentFormat
    private CouponTemplate couponTemplate;

    /** 是否为积分兑换券*/
    @Column(name = "is_credit")
    private boolean credit;
    
    /**
     * default constructor
     */
    public CouponBatch() {
    }

    /**
     * initialize coupon batch using basic fields
     * 
     * @param couponTemplate
     * @return
     */
    public CouponBatch initialize(CouponTemplate couponTemplate) {
        this.createTime = new Date();
        this.couponTemplate = couponTemplate;
        this.templateName = couponTemplate.getName();
        this.releaseAmount = 0;
        this.usedAmount = 0;
        this.claimedAmount = 0;
        return this;
    }
    
    /**
     * 
     * @param creditCouponBatch
     * @return
     */
    public CouponBatch initialize(CreditCouponBatch creditCouponBatch) {
        this.name = creditCouponBatch.getName();
        this.expireType = creditCouponBatch.getExpireType();
        this.effectiveEndDate = creditCouponBatch.getEffectiveEndDate();
        this.effectiveStartDate = creditCouponBatch.getEffectiveStartDate();
        this.effectiveDays = creditCouponBatch.getEffectiveDays();
        this.amount = creditCouponBatch.getAmount();
        this.credit = true;
        return this;
    }

    /**
     * 
     * @return
     */
    public CouponBatch editClaimedAmount() {
        this.claimedAmount++;
        return this;
    }
    
    /**
     * 
     * @param claimedAmount
     * @return
     */
    public CouponBatch editClaimedAmount(int claimedAmount) {
        this.claimedAmount = this.claimedAmount + claimedAmount;
        return this;
    }
    
    /**
     * 
     * @param amount
     * @return
     */
    public CouponBatch editReleaseAmount(int amount) {
        this.releaseAmount = this.releaseAmount + amount;
        return this;
    }
    
    /**
     * 
     * @param templateName
     * @return
     */
    public CouponBatch editTemplateName(String templateName) {
        this.templateName = templateName;
        return this;
    }
    
    /**
     * 
     * @param days
     * @return
     */
    public CouponBatch editEffectiveDays(int days) {
        this.effectiveDays = days;
        return this;
    }
    
    /**
     * 
     * @return
     */
    public CouponBatch editEffectiveDate() {
        this.effectiveStartDate = null;
        this.effectiveEndDate = null;
        return this;
    }
    
    /**
     * 
     * @param expireType
     * @return
     */
    public CouponBatch editExpireType(ExpireType expireType) {
        this.expireType = expireType;
        return this;
    }
    
    /**
     * 获取优惠券剩余可认领的数量
     * 
     * @return
     */
    public int getRestAmount(){
        return this.releaseAmount - this.claimedAmount;
    }
    
    /**
     * 判断优惠券时间是否有效
     * 
     * @return
     */
    public boolean isEffective(){
        if(this.expireType.getDescription() == "fixed_date" && this.effectiveEndDate.before(new Date()))
            return false;
        return true;
    }
    
    /**
     * @return the id
     */
    public Long getId() {
        return this.id;
    }

    /**
     * @return the templateName
     */
    public String getTemplateName() {
        return this.templateName;
    }

    /**
     * @return the name
     */
    public String getName() {
        return this.name;
    }

    /**
     * @return the createTime
     */
    public Date getCreateTime() {
        return this.createTime;
    }

    /**
     * @return the expireType
     */
    public ExpireType getExpireType() {
        return this.expireType;
    }

    /**
     * @return the effectiveStartDate
     */
    public Date getEffectiveStartDate() {
        return this.effectiveStartDate;
    }

    /**
     * @return the effectiveEndDate
     */
    public Date getEffectiveEndDate() {
        return this.effectiveEndDate;
    }

    /**
     * @return the effectiveDays
     */
    public int getEffectiveDays() {
        return this.effectiveDays;
    }

    /**
     * @return the amount
     */
    public int getAmount() {
        return this.amount;
    }

    /**
     * @return the releaseAmount
     */
    public int getReleaseAmount() {
        return this.releaseAmount;
    }

    /**
     * @return the usedAmount
     */
    public int getUsedAmount() {
        return this.usedAmount;
    }

    /**
     * @return the claimedAmount
     */
    public int getClaimedAmount() {
        return this.claimedAmount;
    }

    /**
     * @return the couponTemplate
     */
    public CouponTemplate getCouponTemplate() {
        return this.couponTemplate;
    }

    /**
     * @return the credit
     */
    public boolean isCredit() {
        return this.credit;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param templateName the templateName to set
     */
    public void setTemplateName(String templateName) {
        this.templateName = templateName;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param createTime the createTime to set
     */
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    /**
     * @param expireType the expireType to set
     */
    public void setExpireType(ExpireType expireType) {
        this.expireType = expireType;
    }

    /**
     * @param effectiveStartDate the effectiveStartDate to set
     */
    public void setEffectiveStartDate(Date effectiveStartDate) {
        this.effectiveStartDate = effectiveStartDate;
    }

    /**
     * @param effectiveEndDate the effectiveEndDate to set
     */
    public void setEffectiveEndDate(Date effectiveEndDate) {
        this.effectiveEndDate = effectiveEndDate;
    }

    /**
     * @param effectiveDays the effectiveDays to set
     */
    public void setEffectiveDays(int effectiveDays) {
        this.effectiveDays = effectiveDays;
    }

    /**
     * @param amount the amount to set
     */
    public void setAmount(int amount) {
        this.amount = amount;
    }

    /**
     * @param releaseAmount the releaseAmount to set
     */
    public void setReleaseAmount(int releaseAmount) {
        this.releaseAmount = releaseAmount;
    }

    /**
     * @param usedAmount the usedAmount to set
     */
    public void setUsedAmount(int usedAmount) {
        this.usedAmount = usedAmount;
    }

    /**
     * @param claimedAmount the claimedAmount to set
     */
    public void setClaimedAmount(int claimedAmount) {
        this.claimedAmount = claimedAmount;
    }

    /**
     * @param couponTemplate the couponTemplate to set
     */
    public void setCouponTemplate(CouponTemplate couponTemplate) {
        this.couponTemplate = couponTemplate;
    }

    /**
     * @param credit the credit to set
     */
    public void setCredit(boolean credit) {
        this.credit = credit;
    }
}
